package dev.ece.core.vertex;

import java.nio.FloatBuffer;
import java.util.Iterator;
import java.util.List;

import org.lwjgl.opengl.GL15;

import dev.ece.core.clearup.ClearUpGLRubbish;
import dev.ece.core.clearup.ClearUpGLRubbishManager;
import dev.ece.util.lib.Vector2f;
import dev.ece.util.lib.Vector3f;
import dev.ece.util.lib.Vector4f;
import dev.ece.util.tools.BufferBuilder;
/**
 * vbo绑定
 * 
 * @author 飘渺青衣
 * <b>E-mail：</b>3375758@qq.com
 */
public class VBO implements ClearUpGLRubbish {

	private int vboBufferHandler;
	
	private int count;
	
	private int type;
	
	public int getVboBufferHandler() {
		return vboBufferHandler;
	}

	public VBO() {
		this.vboBufferHandler = GL15.glGenBuffers();
	}
	
	public void bind() {
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.getVboBufferHandler());
	}
	
	public static void unbind() {
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
	}
	
	public int getCount() {
		return count;
	}

	public int getType() {
		return type;
	}

	public void destroy() {
		ClearUpGLRubbishManager.push(this);
	}
	
	public static VBO newInstance(Vector4f[] vectors) {
		VBO vbo = new VBO();
		FloatBuffer buffer = BufferBuilder.buildFloatBuffer(vectors.length * 4 * 4);
		for(int i=0; i<vectors.length; i++) {
			vectors[i].store(buffer);
		}
		buffer.rewind();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.vboBufferHandler);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_READ);
		return vbo;
	}
	
	public static VBO newInstance4f(List<Vector4f> vectors) {
		VBO vbo = new VBO();
		FloatBuffer buffer = BufferBuilder.buildFloatBuffer(vectors.size() * 4 * 4);
		Iterator<Vector4f> it = vectors.iterator();
		while(it.hasNext()) {
			it.next().store(buffer);
		}
		buffer.rewind();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.vboBufferHandler);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_READ);
		return vbo;
	}
	
	public static VBO newInstance(Vector3f[] vectors) {
		VBO vbo = new VBO();
		FloatBuffer buffer = BufferBuilder.buildFloatBuffer(vectors.length * 3 * 4);
		for(int i=0; i<vectors.length; i++) {
			vectors[i].store(buffer);
		}
		buffer.rewind();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.vboBufferHandler);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_READ);
		return vbo;
	}
	
	public static VBO newInstance3f(List<Vector3f> vectors) {
		VBO vbo = new VBO();
		FloatBuffer buffer = BufferBuilder.buildFloatBuffer(vectors.size() * 3 * 4);
		Iterator<Vector3f> it = vectors.iterator();
		while(it.hasNext()) {
			it.next().store(buffer);
		}
		buffer.rewind();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.vboBufferHandler);
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_READ);
		return vbo;
	}
	
	public static VBO newInstance(Vector2f[] vectors) {
		VBO vbo = new VBO();
		FloatBuffer buffer = BufferBuilder.buildFloatBuffer(vectors.length * 2 * 4);
		for(int i=0; i<vectors.length; i++) {
			vectors[i].store(buffer);
		}
		buffer.rewind();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.getVboBufferHandler());
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_READ);
		return vbo;
	}
	
	public static VBO newInstance2f(List<Vector2f> vectors) {
		VBO vbo = new VBO();
		FloatBuffer buffer = BufferBuilder.buildFloatBuffer(vectors.size() * 2 * 4);
		Iterator<Vector2f> it = vectors.iterator();
		while(it.hasNext()) {
			it.next().store(buffer);
		}
		buffer.rewind();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.getVboBufferHandler());
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_READ);
		return vbo;
	}
	
	public static VBO newInstance(float[] buffers) {
		VBO vbo = new VBO();
		FloatBuffer buffer = BufferBuilder.buildFloatBuffer(buffers.length * 4);
		for(int i=0; i<buffers.length; i++) {
			buffer.put(buffers[i]);
		}
		buffer.rewind();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.getVboBufferHandler());
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_READ);
		return vbo;
	}
	
	public static VBO newInstance1f(List<Float> buffers) {
		VBO vbo = new VBO();
		FloatBuffer buffer = BufferBuilder.buildFloatBuffer(buffers.size() * 4);
		Iterator<Float> it = buffers.iterator();
		while(it.hasNext()) {
			buffer.put(it.next());
		}
		buffer.rewind();
		GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo.getVboBufferHandler());
		GL15.glBufferData(GL15.GL_ARRAY_BUFFER, buffer, GL15.GL_STATIC_READ);
		return vbo;
	}
	
	@Override
	public void clearup() {
		GL15.glDeleteBuffers(vboBufferHandler);
	}
}
